package dmas.lab.tasks;

import java.math.BigInteger;
import java.util.List;
import java.util.Random;

import dmas.lab.helpers.Helpers;
import dmas.lab.models.Contact;
import dmas.lab.models.Friend;
import dmas.lab.models.Group;
import dmas.lab.models.Message;
import dmas.lab.schedulers.Event;
import dmas.lab.schedulers.Scheduler;
import dmas.lab.schedulers.TaskCaller;

public class SendSpamEvent extends Event {

	private double repostProbability;
	private final int senderID;
	private final int receiverID;
	private Group group = Group.getGroup();

	public SendSpamEvent(BigInteger eventID, TaskCaller taskCaller, Message message) {
		super(eventID, taskCaller);
		this.senderID = message.getSenderID();
		this.receiverID = message.getReceiverID();
	}

	@Override
	public Event runTask() throws Exception {

		Contact authorContact = group.getContact(senderID);

		if (isReposting(authorContact)) {
			int numberOfFriends = authorContact.getFriends().size();
			int sendToCount = (int) (numberOfFriends * repostProbability);

			List<Friend> friends = authorContact.getFriends();
			for (Friend friend : friends) {
				if (sendToCount > 0 && friend.getState().equals("hated")
						|| friend.getState().equals("neutral")) {
					Contact currentFriend = group.getContact(friend.getID());
					sendMessageToFriend(authorContact, currentFriend);
					sendToCount--;
				}
			}
		}else{
			System.out.println(String.format("Event id: %s, Sender ID: %s, IGNORED", getEventID(), authorContact.getID()));
			setIgnored(true);
		}
		return this;
	}

	private boolean isReposting(Contact authorContact) {
		return isProbable(authorContact) && (senderID != receiverID);
	}
	
	private boolean isProbable(Contact contact) {
		repostProbability = Helpers.getProbability(contact.getFriends().size(), group.getSize());
		double dd = Helpers.getRandomDouble();
		return (repostProbability >= dd);
	}

	private void sendMessageToFriend(Contact authorContact, Contact friend) {
		int indexOfChanged = friend.getFriends().indexOf(authorContact);
		Friend sendToFriend = authorContact;
		sendToFriend.setState("hated");
		friend.getFriends().set(indexOfChanged, sendToFriend);

		System.out.println(String.format("Event id: %s, Sender ID: %s, Receiver ID: %s", getEventID(),authorContact.getID(), friend.getID()));
		launchNewEvent(authorContact.getID(), friend.getID());
	}

	private void launchNewEvent(int fromID, int toID) {
		Scheduler scheduler = (Scheduler) getCallback();
		scheduler.addEvent(new ReceiveMessageEvent(BigInteger.probablePrime(16, new Random()), scheduler, new Message(fromID, toID)));
	}
}